#include<string.h>
#include<errno.h>
#include<stdio.h>
#include<stdlib.h>
#include"http_resp.h"

/*释放和初始化的共同操作*/
void http_resp_init_destroy_comm(http_resp *resp_p)
{
	resp_p->packet_buf.resp_buf = NULL;
	resp_p->packet_buf.resp_buf_size = 0;

	//resp_p->resp_buf = NULL;/*这个缓冲区是来自get_page_through_url函数*/

	resp_p->status_line.ver.major_ver = 0;
	resp_p->status_line.ver.minor_ver = 0;
	resp_p->status_line.status_code = 0;
	resp_p->status_line.phrase = NULL;
	resp_p->header_line.header_num = 0;

	for (int i=0; i<MAX_HEADERS_LINE; i++){
		resp_p->header_line.header[i] = NULL;
		resp_p->header_line.value[i]  = NULL;
	}
	resp_p->content.body = NULL;
	resp_p->content.body_length = 0;
}

int http_resp_init(http_resp *resp_p)
{
	if (NULL == resp_p){
		return -1;
	}
	http_resp_init_destroy_comm(resp_p);

	return 0;
}

int http_resp_destroy(http_resp *resp_p)
{
	if (NULL == resp_p){
		return -1;
	}

	/*
	if (resp_p->resp_buf != NULL){
		free(resp_p->resp_buf);
		resp_p->resp_buf = NULL;
	}*/

	if (resp_p->packet_buf.resp_buf != NULL){
		free(resp_p->packet_buf.resp_buf);
	}

	http_resp_init_destroy_comm(resp_p);

	return 0;
}

int http_set_resp_buf(char *resp_buf, int buf_size, http_resp *resp_p)
{
	if (NULL == resp_buf
	 ||	NULL == resp_p
	 ){
		return -1;
	}
	resp_p->packet_buf.resp_buf = resp_buf;
	resp_p->packet_buf.resp_buf_size = buf_size;
	return 0;
}

int parse_status_line(char *status_line, http_resp *resp_p)
{
	char *tmp1 = NULL;
	char *tmp2 = NULL;
	//int val;

	if ((NULL == status_line) || (NULL == resp_p)){
		return -1;
	}

	tmp1 = strstr(status_line, "HTTP/");
	if (NULL == tmp1){
		return -2;
	}
	tmp1 += strlen("HTTP/");

	tmp2 = strstr(tmp1, ".");
	if (NULL == tmp2){
		return -3;
	}
	*tmp2 = '\0';
	/*strtol函数，查错功能更强*/
	resp_p->status_line.ver.major_ver = atoi(tmp1);

	tmp2 += strlen(".");

	tmp1 = strstr(tmp2," ");
	if (NULL == tmp1){
		return -4;
	}
	*tmp1 = '\0';
	resp_p->status_line.ver.minor_ver = atoi(tmp2);

	tmp1 += strlen(" ");

	tmp2 = strstr(tmp1, " ");
	if (NULL == tmp2){
		return -5;
	}
	*tmp2 = '\0';
	tmp2 += strlen(" ");
	resp_p->status_line.status_code = atoi(tmp1);
	/*这里已经是HTTP/1.1 200 OK，没有\r\n了*/
	/*
	tmp1 = strstr(tmp2, "\r\n");
	if (NULL == tmp1){
		return -6;
	}
	*tmp1 = '\0';
	*/
	resp_p->status_line.phrase = tmp2;
	return 0;
}

int parse_header_line(char *header_line, http_resp *resp_p)
{
	char *tmp1 = NULL;
	char *tmp2 = NULL;

	if ((NULL == header_line) || (NULL == resp_p)){
		return -1;
	}

	if (resp_p->header_line.header_num >= MAX_HEADERS_LINE){
		return -2;
	}

	tmp1 = strstr(header_line, ": ");
	if (NULL == tmp1){
		return -2;
	}

	*tmp1 = '\0';
	resp_p->header_line.header[resp_p->header_line.header_num] = header_line;

	tmp1 += strlen(": ");

	/*
	tmp2 = strstr(tmp1, "\r\n");
	if (NULL == tmp2){
		return -3;
	}
	*tmp2 = '\0';
	*/
	resp_p->header_line.value[resp_p->header_line.header_num] = tmp1;
	resp_p->header_line.header_num++;
	return 0;
}

int parse_resp_packet(http_resp *resp_p)
{
	char *tmp1 = NULL;
	char *tmp2 = NULL;
	char *status_line = NULL;
	char *header_line = NULL;
	char *resp_buf = NULL;
	int buf_size = NULL;
	unsigned int i = 0;

	parse_status cur_status = STATUS_LINE;

	if ((NULL == resp_p)
	||   NULL == resp_p->packet_buf.resp_buf){
		return -1;
	}
	/*这个指针用于操作完这片缓冲区后释放它*/
	//resp_p->resp_buf = resp_buf;
	resp_buf = resp_p->packet_buf.resp_buf;
	buf_size = resp_p->packet_buf.resp_buf_size;

	tmp1 = resp_buf;
	tmp2 = strstr(tmp1, "\r\n");
	if ((NULL == tmp2) && (cur_status != FINISHED)){
		return -2;
	}

	/*发现状态行*/
	*tmp2 = '\0';
	status_line = tmp1;

	cur_status = HEADER_LINE;
	if (parse_status_line(status_line, resp_p) < 0){
		return -3;
	}

	/*填充好了状态行，那么我们需要判断是否是我们需要的*/
	/*还没有处理302重定向*/
	if (resp_p->status_line.status_code != 200){
		return -4;
	}

	tmp1 = tmp2 + strlen("\r\n");

	/*下面对data部分的处理还是不太对*/
	while(1){

		tmp2 = strstr(tmp1, "\r\n");
		if (tmp2 == NULL){
			//return -4;
			return -5;
		}

		if (tmp2 == tmp1){
			/*说明tmp1指向的就是\r\n，说明这行没有内容了，应该是\r\n\r\n*/
			cur_status = FINISHED;
			resp_p->content.body = tmp1 + strlen("\r\n");
			resp_p->content.body_length = buf_size - (tmp1 + strlen("\r\n") - resp_buf + 1);
			break;
		}

		/*发现首部行*/
		*tmp2 = '\0';
		//header_line = strdup(tmp1);
		header_line = tmp1;
		if (parse_header_line(header_line, resp_p) < 0){
			//return -5;
			return -6;
		}
		tmp1 = tmp2 + strlen("\r\n");
	}

#if 0
	for (i=0; i<resp_p->header_line.header_num; i++){

		if (resp_p->header_line.header[i] != NULL
		&&  resp_p->header_line.value[i] != NULL ){

			if (
				strncasecmp(resp_p->header_line.header[i],"Content-Type",strlen("Content-Type"))== 0
				){
				/*当有Content-Type首部行的时候，我们必须要确定文件内容是html的，如果没有的话，就算了*/
				if (
				  strncasecmp(resp_p->header_line.header[i],"text/html",strlen("text/html"))!=0
				   ){
					fprintf(stderr,"this resp packet is not HTML\n");
					return -7;
				}else{
					/*如果是html的话，就直接返回正确了。*/
					break;
				}
			}
		}
	}
	//if ()
#endif

	return 0;
}


